package com.graduation.smartparkingplatform.Controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.graduation.smartparkingplatform.Pojo.PlateOCR;
import com.graduation.smartparkingplatform.Response.Response;
import com.graduation.smartparkingplatform.Response.ResponseUtils;
import com.graduation.smartparkingplatform.Service.DiscernService;
import com.graduation.smartparkingplatform.WebSocket.WebSocket;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.LicensePlateOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.LicensePlateOCRResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.UUID;

@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/discern")
public class DiscernController {

  @Autowired DiscernService discernService;
  @Autowired RedisTemplate redisTemplate;

  @Value("${Myserver.ip}")
  private String ip;

  @Value("${discern.carPlateInImgPath}")
  private String carPlateInImgPath;

  @Value("${discern.carPlateOutImgPath}")
  private String carPlateOutImgPath;

  @Value("${txCloud.secretId}")
  private String secretId;

  @Value("${txCloud.secretKey}")
  private String secretKey;

  @Value("${txCloud.httpClientProfile}")
  private String httpClientProfile;

  @Value("${txCloud.region}")
  private String region;

  // 进场识别
  @PostMapping("/sendCarPlate-In")
  public Response sendCarPlateIn(@RequestParam("file") MultipartFile multipartFile) {
    String fileUrl = null;
    if (multipartFile.isEmpty()) {
      return ResponseUtils.buildPARAM_ERROR();
    }
    String fileName = multipartFile.getOriginalFilename();
    fileName = UUID.randomUUID() + "_" + fileName;
    //    String dirPath = "F:/毕业设计/上传文件测试/CarPlate/";
    File filePath = new File(carPlateInImgPath);
    if (!filePath.exists()) {
      filePath.mkdirs();
    }
    try {
      String fullPath = carPlateInImgPath + fileName; // 硬盘储存路径全称
      multipartFile.transferTo(new File(fullPath));
      Thread.sleep(3000);
      fileUrl = ip + "/image/CarPlateIn/" + fileName; // 需根据实际地址进行修改

      Credential cred = new Credential(secretId, secretKey);
      // 实例化一个http选项，可选的，没有特殊需求可以跳过
      HttpProfile httpProfile = new HttpProfile();
      httpProfile.setEndpoint(httpClientProfile);
      // 实例化一个client选项，可选的，没有特殊需求可以跳过
      ClientProfile clientProfile = new ClientProfile();
      clientProfile.setHttpProfile(httpProfile);
      // 实例化要请求产品的client对象,clientProfile是可选的
      OcrClient client = new OcrClient(cred, region, clientProfile);
      // 实例化一个请求对象,每个接口都会对应一个request对象
      LicensePlateOCRRequest req = new LicensePlateOCRRequest();
      req.setImageUrl(fileUrl);
      // 返回的resp是一个LicensePlateOCRResponse的实例，与请求对象对应
      LicensePlateOCRResponse resp = client.LicensePlateOCR(req);

      // 输出json格式的字符串回包
      String jsonString = LicensePlateOCRResponse.toJsonString(resp);

      // 转换Json转换成Java对象
      PlateOCR plateOCR = JSONArray.parseObject(jsonString, PlateOCR.class);
      String carPlate = plateOCR.getNumber();
      Integer confidence = plateOCR.getConfidence();
      String requestId = plateOCR.getRequestId();

      // 获取当前时间
      Calendar calendar = Calendar.getInstance();
      // 定义时间格式化
      SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String nowTime = formatter.format(calendar.getTime());

      // 将车牌存入reids缓存
      redisTemplate.boundValueOps("carPlate_" + carPlate).set(nowTime);

      Boolean changeInfo = discernService.addRecordIn(carPlate, fileUrl, confidence, requestId);
      // 写入webSocket消息
      JSONObject result = new JSONObject();
      result.put("webSocketId", 7);
      result.put("carPlate", carPlate);
      result.put("type", "进");
      result.put("time", nowTime);
      WebSocket.sendInfo(result.toJSONString());
      if (changeInfo) {
        redisTemplate.opsForValue().set("Railing_in", "car_open");
        //        return ResponseUtils.buildSuccess("车牌识别成功-进", carPlate);
        log.info("CarPlate:" + carPlate + "sendCarPlate-In");
        return ResponseUtils.buildSuccess(plateOCR);
      }
    } catch (Exception e) {
      log.error("sendCarPlate-In error-" + e);
      return ResponseUtils.buildSYSTEM_ERROR(e);
    }
    return ResponseUtils.buildSYSTEM_ERROR();
  }
  // 出场识别
  @PostMapping("/sendCarPlate-Out")
  public Response sendCarPlateOut(@RequestParam("file") MultipartFile multipartFile) {
    String fileUrl = null;
    if (multipartFile.isEmpty()) {
      return ResponseUtils.buildPARAM_ERROR();
    }
    String fileName = multipartFile.getOriginalFilename();
    fileName = UUID.randomUUID() + "_" + fileName;
    //    String dirPath = "F:/毕业设计/上传文件测试/CarPlate/";
    File filePath = new File(carPlateOutImgPath);
    if (!filePath.exists()) {
      filePath.mkdirs();
    }
    try {
      String fullPath = carPlateOutImgPath + fileName; // 硬盘储存路径全称
      multipartFile.transferTo(new File(fullPath));
      Thread.sleep(3000);
      fileUrl = ip + "/image/CarPlateOut/" + fileName; // 需根据实际地址进行修改

      Credential cred = new Credential(secretId, secretKey);
      // 实例化一个http选项，可选的，没有特殊需求可以跳过
      HttpProfile httpProfile = new HttpProfile();
      httpProfile.setEndpoint(httpClientProfile);
      // 实例化一个client选项，可选的，没有特殊需求可以跳过
      ClientProfile clientProfile = new ClientProfile();
      clientProfile.setHttpProfile(httpProfile);
      // 实例化要请求产品的client对象,clientProfile是可选的
      OcrClient client = new OcrClient(cred, region, clientProfile);
      // 实例化一个请求对象,每个接口都会对应一个request对象
      LicensePlateOCRRequest req = new LicensePlateOCRRequest();
      req.setImageUrl(fileUrl);
      // 返回的resp是一个LicensePlateOCRResponse的实例，与请求对象对应
      LicensePlateOCRResponse resp = client.LicensePlateOCR(req);

      // 输出json格式的字符串回包
      String jsonString = LicensePlateOCRResponse.toJsonString(resp);

      // 转换Json转换成Java对象
      PlateOCR plateOCR = JSONArray.parseObject(jsonString, PlateOCR.class);
      String carPlate = plateOCR.getNumber();
      Integer confidence = plateOCR.getConfidence();
      String requestId = plateOCR.getRequestId();

      Boolean delRedis = redisTemplate.delete("carPlate_" + carPlate);

      Boolean changeInfo = discernService.addRecordOut(carPlate, fileUrl, confidence, requestId);
      // 获取当前时间
      Calendar calendar = Calendar.getInstance();
      // 定义时间格式化
      SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String nowTime = formatter.format(calendar.getTime());
      JSONObject result = new JSONObject();
      result.put("webSocketId", 8);
      result.put("carPlate", carPlate);
      result.put("type", "出");
      result.put("time", nowTime);
      WebSocket.sendInfo(result.toJSONString());
      if (changeInfo) {
        redisTemplate.opsForValue().set("Railing_in", "car_open");
        log.info("CarPlate:" + carPlate + "sendCarPlate-Out");
        return ResponseUtils.buildSuccess(plateOCR);
      }
    } catch (Exception e) {
      log.error("sendCarPlate-Out error-" + e);
      return ResponseUtils.buildSYSTEM_ERROR(e);
    }
    return ResponseUtils.buildSYSTEM_ERROR();
  }
}
